<script lang="tsx" name="ApiCheckbox">
  /**
   *  title
   * @description: description
   * @author SunYanMing<95317356@qq.com>
   * @property {Boolean} props desc info
   * @example <ApiCheckbox />
   * @date 2023/11/16
   */
  import { defineComponent, onMounted, ref, watch, toValue } from 'vue';
  import { get, noop, cloneDeep } from 'lodash-es';

  export default defineComponent({
    name: 'ApiCheckbox',

    inheritAttrs: true,
    props: {
      prop: {
        type: String,
        default: '',
      },
      formData: {
        type: Object,
        default: () => ({}),
      },
      modelValue: {
        type: [String, Number, Array],
        default: undefined,
      },
      // 携带参数 返回一个携带对象
      params: {
        type: [Function, Object],
        default: noop,
      },
      apiBefore: {
        type: Function,
        default: noop,
      },
      apiAfter: {
        type: Function,
        default: noop,
      },
      api: {
        type: Function,
        default: null,
      },
      labelField: {
        type: String,
        default: 'label',
      },
      valueField: {
        type: String,
        default: 'value',
      },
      resultField: {
        type: String,
        default: 'rows',
      },
      onChange: {
        type: Function,
        default: noop,
      },
      componentProps: {
        type: Object,
        default: () => ({}),
      },
    },

    emits: ['update:modelValue'],
    setup(props, cxt) {
      const options = ref([]);

      const value = ref(props.modelValue);

      watch(
        () => value.value,
        (val) => {
          cxt.emit('update:modelValue', toValue(val));
        },
        {
          immediate: true,
        },
      );

      const colApiOptionsProxy = async () => {
        const { api, params } = props;
        if (typeof api === 'function') {
          let _params = {};
          if (typeof params === 'function') {
            _params = params(cloneDeep(props.formData)) ?? {};
          } else {
            _params = props.apiBefore(params, cloneDeep(props.formData)) ?? params;
          }
          api(_params ?? {}).then((res) => {
            const _res = props.apiAfter(res) ?? res;
            options.value = get(_res, props.resultField) ?? [];
          });
        }
      };

      onMounted(() => {
        colApiOptionsProxy();
        // 监听某字典发生变化时触发拉取api代理列表
        if (props.componentProps.watchPropsChangeApi) {
          let _oldValue = {};
          watch(
            () => props.formData,
            (value) => {
              const _value = toValue(value);
              const keys =
                typeof props.componentProps.watchPropsChangeApi === 'string'
                  ? [props.componentProps.watchPropsChangeApi]
                  : props.componentProps.watchPropsChangeApi;
              keys.map((key: string) => {
                // console.log(key, get(_value, key), get(_oldValue, key));
                if (get(_value, key) !== get(_oldValue, key)) {
                  colApiOptionsProxy();
                }
              });

              _oldValue = cloneDeep(toValue(value) ?? {});
            },
            {
              // immediate: true,
              deep: true,
            },
          );
        }
      });

      return {
        value,
        options,
      };
    },
  });
</script>

<template>
  <el-checkbox-group v-model="value" v-bind="{ ...componentProps, ...$attrs }" @change="onChange">
    <template #[key]="slotData" v-for="key in Object.keys($slots)">
      <slot :name="key" v-bind="slotData || {}"></slot>
    </template>

    <el-checkbox
      v-for="item in options"
      :label="item[valueField]"
      :value="item[valueField]"
      :key="item[valueField]"
    >
      {{ item[labelField] }}
    </el-checkbox>
  </el-checkbox-group>
</template>
<style scoped></style>
